#ifndef _LINUX_PAGEMAP_H
#define _LINUX_PAGEMAP_H

#include <linux/types.h>
#include <linux/gfp.h>
#include <linux/fs2.h>

#include <asm/page.h>

#define PAGE_CACHE_SHIFT	PAGE_SHIFT
#define PAGE_CACHE_SIZE		PAGE_SIZE
#define PAGE_CACHE_MASK		PAGE_MASK

static inline loff_t page_offset(struct page *page)
{
	return ((loff_t)page->index) << PAGE_CACHE_SHIFT;
}

static inline gfp_t mapping_gfp_mask(struct address_space * mapping)
{
	return (gfp_t)mapping->flags & __GFP_BITS_MASK;
}

static inline struct page *__page_cache_alloc(gfp_t gfp)
{
	printf("this is %s(): %d\r\n", __func__, __LINE__);
	// return alloc_pages(gfp, 0);
	return alloc_pages(gfp, 1);
}

static inline struct page *page_cache_alloc_cold(struct address_space *x)
{
	return __page_cache_alloc(mapping_gfp_mask(x)|__GFP_COLD);
}

static inline int add_to_page_cache(struct page *page,
		struct address_space *mapping, pgoff_t offset, gfp_t gfp_mask)
{
	int error;

	// __set_page_locked(page);
	error = add_to_page_cache_locked(page, mapping, offset, gfp_mask);
	// if (unlikely(error))
	// 	__clear_page_locked(page);
	return error;
}

typedef int filler_t(void *, struct page *);

extern struct page * find_or_create_page(struct address_space *mapping,
				pgoff_t index, gfp_t gfp_mask);
extern struct page * read_cache_page(struct address_space *mapping,
				pgoff_t index, filler_t *filler,
				void *data);

/*
 * Returns locked page at given index in given cache, creating it if needed.
 */
static inline struct page *grab_cache_page(struct address_space *mapping,
								pgoff_t index)
{
	return find_or_create_page(mapping, index, mapping_gfp_mask(mapping));
}

static inline struct page *read_mapping_page(struct address_space *mapping,
					     pgoff_t index, void *data)
{
	printf("this is %s(): %d\r\n", __func__, __LINE__);
	filler_t *filler = (filler_t *)mapping->a_ops->readpage;
	return read_cache_page(mapping, index, filler, data);
}

#endif
